﻿#pragma once
#include <graphics.h>
#include <cmath>;
namespace sy
{
namespace draw 
{
	int screenX = 800;	// 屏幕宽度
	int screenY = 800;	// 屏幕高度

	float View2Screen;	// 视口坐标转换成屏幕坐标比例

	#define _x(x) (int)(x + View2Screen)
	#define _y(y) (int)(-y + View2Screen)		// 坐标系转换到屏幕中间

	void Putpixel(float x, float y, COLORREF color = RGB(255, 255, 255))
	{
		putpixel(_x(x), _y(y), color);
	}

	void Putpixel(float x, float y, float color)
	{
		color = abs(color) * 255;
		Putpixel(x, y, RGB(color, color, color));
	}

	void Line(float x1, float y1, float x2,float y2, COLORREF color = RGB(255, 255, 255))
	{
		setlinecolor(color);
		line(_x(x1), _y(y1), _x(x2), _y(y2));
	}

	struct Point
	{
		union 
		{
			float data[3];
			struct { float x, y, z; };
		};
		Point(float _x = 0.0f, float _y = 0.0f, float _z= 0.0f) :x(_x), y(_y),z(_z) {}
		Point(const Point& p) :x(p.x), y(p.y), z(p.z) { }
		Point& operator=(const Point& p) { x = p.x; y = p.y; z = p.z; }
	};

	struct Color
	{
		union
		{
			float data[3];
			struct { float r, g, b; };
		};
		Color(float _r = 0.0f, float _g = 0.0f, float _b = 0.0f) :r(_r), g(_g), b(_b) {}
		Color(const Color& p) :r(p.r), g(p.g), b(p.b) { }
		Color& operator=(const Color& p) { r = p.r; g = p.g; b = p.b; }
	};

	struct Triangle
	{
		union vertice	// 顶点
		{
			Point data[3];
			struct { Point A, B, C; };
		};
		union colors	// 顶点的颜色
		{
			Color data[3];
			struct { Color A, B, C; };
		};

	};

	class Canvas
	{
	public:
		static Canvas* GetInstance()
		{
			static Canvas instance;
			return &instance;
		}

		void InitCanvas(int width = screenX, int height = screenY,bool console = false)
		{
			initgraph(width, height);
			BeginBatchDraw();
			screenX = width;
			screenY = height;
			View2Screen = screenX / 2;
			dp_screenBuffer = GetImageBuffer(NULL);
		}
		void Putpixel(float x, float y, COLORREF color = RGB(255, 255, 255))
		{
			int index = _y(int(y)) * screenX + _x(int(x));
			if (index < 0 || index >= screenX * screenY) return;
			dp_screenBuffer[index] = color;
		}
		void Putpixel(float x, float y, float color)
		{
			color = abs(color) * 255;
			Putpixel(x, y, RGB(color, color, color));
		}
		void Line(float x1, float y1, float x2, float y2, COLORREF color = RGB(255, 255, 255))
		{
			setlinecolor(color);
			line(_x(x1), _y(y1), _x(x2), _y(y2));
		}
		
		void RenderTriangle(POINT A, POINT B, POINT C, COLORREF cA, COLORREF cB, COLORREF cC)		// 三角形重心坐标插值进行绘制
		{

		}

		void RenderTriangle(POINT A, POINT B, POINT C)		// 线框三角形						
		{

		}
		
		void RenderTriangle(POINT A, POINT B, POINT C, POINT)		// UV 贴图三角形						
		{

		}

		void RenderTriangle(const Triangle& tri)
		{
			
		}
		void RenderTriangle(Point A, Point B, Point C)
		{

		}
		void Show()
		{
			FlushBatchDraw();
		}
		void Close()
		{
			EndBatchDraw();
			closegraph();
		}

	private:
		DWORD* dp_screenBuffer;

	private:
		Canvas()
		{
			dp_screenBuffer = nullptr;
		}
		Canvas(const Canvas&) = delete;
		Canvas& operator=(const Canvas&) = delete;


	};
}
}